package com.ruoyi.lock.controller;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.lock.domain.*;
import com.ruoyi.lock.domain.dto.BatchAddTenantkeyDto;
import com.ruoyi.lock.mapper.AHomeUserMapper;
import com.ruoyi.lock.service.IABuildHomeService;
import com.ruoyi.lock.service.IADeviceService;
import com.ruoyi.lock.service.IATenantkeyService;
import com.ruoyi.lock.service.IATenantuserService;
import com.ruoyi.locksApi.domain.ATask;
import com.ruoyi.locksApi.mapper.ATaskMapper;
import com.ruoyi.locksApi.service.LockApiService;
import com.ruoyi.websocket.WebSocketEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Base64;
import com.ruoyi.lock.service.IAHomeUserService;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * 钥匙Controller
 *
 * @author arvin
 * @date 2025-03-06
 */
@RestController
@RequestMapping("/lock/tenantkey")
public class ATenantkeyController extends BaseController
{
    @Autowired
    private IATenantkeyService aTenantkeyService;
    @Autowired
    private IADeviceService iaDeviceService;
    @Autowired
    private ATaskMapper taskMapper;
    @Autowired
    private LockApiService lockApiService;
    @Autowired
    private IATenantuserService aTenantuserService;
    @Autowired
    private IABuildHomeService aBuildHomeService;
    @Autowired
    private IAHomeUserService aHomeUserService;
    @Autowired
    private AHomeUserMapper aHomeUserMapper;
    


    private final ExecutorService customExecutor = Executors.newFixedThreadPool(10);

    /**
     * 查询钥匙列表
     */
    @PreAuthorize("@ss.hasPermi('lock:tenantkey:list')")
    @GetMapping("/list")
    public TableDataInfo list(ATenantkey aTenantkey)
    {
        startPage();
        List<ATenantkey> list = aTenantkeyService.selectATenantkeyList(aTenantkey);
        return getDataTable(list);
    }  /**
     * 查询钥匙列表
     */
    @GetMapping("/list2")
    public TableDataInfo list2(ATenantkey aTenantkey)
    {
        startPage();
        List<ATenantkey> list = aTenantkeyService.selectATenantkeyList2(aTenantkey);
        return getDataTable(list);
    }

    /**
     * 导出钥匙列表
     */
    @PreAuthorize("@ss.hasPermi('lock:tenantkey:export')")
    @Log(title = "钥匙", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ATenantkey aTenantkey)
    {
        List<ATenantkey> list = aTenantkeyService.selectATenantkeyList(aTenantkey);
        for (ATenantkey tenantkey : list) {
            if(tenantkey.getFlgDelete()==0L){
                tenantkey.setFlgDeleteString("删除");
            }else{
                tenantkey.setFlgDeleteString("正常");

            }
            if("1".equals(tenantkey.getType())){
                tenantkey.setType("密码");
            }else if("2".equals(tenantkey.getType())) {
                tenantkey.setType("卡片");

            }
            if(tenantkey.getStatus()==0L){
                tenantkey.setStatusString("未生效");
            }else{
                tenantkey.setStatusString("已生效");

            }
            if(tenantkey.getIsItAvailable()==0L){
                tenantkey.setIsItAvailableString("未冻结");
            }else{
                tenantkey.setIsItAvailableString("已冻结");

            }
        }
        ExcelUtil<ATenantkey> util = new ExcelUtil<ATenantkey>(ATenantkey.class);
        util.exportExcel(response, list, "钥匙数据");
    }

    /**
     * 获取钥匙详细信息
     */
    @PreAuthorize("@ss.hasPermi('lock:tenantkey:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(aTenantkeyService.selectATenantkeyById3(id));
    }

    /**
     * 新增钥匙
     */
    @PreAuthorize("@ss.hasPermi('lock:tenantkey:add')")
    @Log(title = "钥匙", businessType = BusinessType.INSERT)
    @PostMapping
    @Transactional
    public AjaxResult add(@RequestBody ATenantkey aTenantkey)
    {

        // 验证结束时间不早于开始时间
        if (aTenantkey.getEndTime().before(aTenantkey.getStartTime()) || aTenantkey.getEndTime().equals(aTenantkey.getStartTime())) {
            return error("结束时间不能早于或等于开始时间");
        }

        // 检查卡片类型时，验证卡号是否已在该房间中存在
        if ("2".equals(aTenantkey.getType()) && StringUtils.isNotEmpty(aTenantkey.getCardNo())) {
            ATenantkey checkKey = new ATenantkey();
            checkKey.setHomeId(aTenantkey.getHomeId());
            checkKey.setCardNo(aTenantkey.getCardNo());
            checkKey.setType("2"); // 卡片类型
            List<ATenantkey> existingKeys = aTenantkeyService.selectATenantkeySimple(checkKey);
            
            if (existingKeys != null && !existingKeys.isEmpty()) {
                return error("该房间中已存在此卡号，请勿重复办理");
            }
        }

        if ("1".equals(aTenantkey.getType()) && StringUtils.isNotEmpty(aTenantkey.getPassword())) {
            ATenantkey checkKey = new ATenantkey();
            checkKey.setHomeId(aTenantkey.getHomeId());
            checkKey.setPassword(aTenantkey.getPassword());
            checkKey.setType("1"); // 密码
            List<ATenantkey> existingKeys = aTenantkeyService.selectATenantkeySimple(checkKey);

            if (existingKeys != null && !existingKeys.isEmpty()) {
                return error("该房间中已存在此密码，请勿重复办理");
            }
        }

//        ATenantkey aTenantkey1 = new ATenantkey();
//        aTenantkey1.setPassword(aTenantkey.getPassword());
//        List<ATenantkey> list = aTenantkeyService.selectATenantkeyList3(aTenantkey1);
//        if (list.size()>0){
//            throw new RuntimeException("密码已经存在请更换一个密码!");
//        }


//        JSONObject data = new JSONObject();

        ATenantuser aTenantuser = aTenantuserService.selectATenantuserById(aTenantkey.getTenantId());
        AHomeUser aHomeUser = new AHomeUser();
        aHomeUser.setHomeId(aTenantkey.getHomeId());
        aHomeUser.setUserId(aTenantkey.getTenantId());
        String keyGroupId3 =null;

        AHomeUser aHomeUser1 = aHomeUserMapper.selectAHomeUserList2(aHomeUser);

        if(aTenantkey.getType().equals("1")){
            System.err.println(aHomeUser1.getStartTime());
            System.err.println(aHomeUser1.getEndTime());
            //卡片
            Long beginTime = aHomeUser1.getStartTime() == null ? null : aHomeUser1.getStartTime().getTime() / 1000;
            Long endTime = aHomeUser1.getEndTime() == null ? null : aHomeUser1.getEndTime().getTime() / 1000;
            ABuildHome aBuildHome = aBuildHomeService.selectABuildHomeById2(aTenantkey.getHomeId());


            if (aHomeUser1!=null){
                String keyGroupId2 = aHomeUser1.getKeyGroupId();
                if(StringUtils.isNotEmpty(keyGroupId2)){
                    keyGroupId3=keyGroupId2;
                }
            }

            JSONObject jsonObject = lockApiService.apartmentAddPwdKey(
                    aBuildHome.getRoomNum(),
                    aTenantuser.getPhone(),
                    aTenantuser.getName(),
                    beginTime,
                    endTime,
                    aTenantkey.getPassword(),
                    keyGroupId3
                    ,aTenantuser.getIdCardNumber()
            );

            int resultCode = jsonObject.getIntValue("resultCode");
            if (resultCode != 0) {
                String reason = jsonObject.getString("reason");
                // 你可以根据不同的错误码自定义提示
                switch (resultCode) {
                    case 500001:
                        throw new RuntimeException("参数异常: " + reason);
                    case 500002:
                        throw new RuntimeException("房间不存在: " + reason);
                    case 500003:
                        throw new RuntimeException("房间未关好门锁: " + reason);
                    case 500004:
                        throw new RuntimeException("密码不能为空: " + reason);
                    case 500005:
                        throw new RuntimeException("密码不合法: " + reason);
                    case 500006:
                        throw new RuntimeException("暂不支持该房间授权: " + reason);
                    default:
                        throw new RuntimeException("远程发卡失败: " + reason);
                }
            }

            // 获取keyId并存入
            String keyId = null;
            String keyGroupId = null;
            if (jsonObject.containsKey("data")) {
                JSONObject dataObj = jsonObject.getJSONObject("data");
                keyId = dataObj.getString("keyId");
                keyGroupId = dataObj.getString("keyGroupId");
            }
            aTenantkey.setKeyGroupId(keyGroupId);
            aTenantkey.setPwdId(keyId);
            //往key表插入数据
            aTenantkey.setStatus(0);
            aTenantkey.setRemark("下发授权");
            // 在插入aTenantkey之前，更新AHomeUser的keyGroupId
            aHomeUserService.updateKeyGroupIdByHomeIdAndUserId(aTenantkey.getHomeId(),aTenantkey.getTenantId(),keyGroupId);

        }

        if(aTenantkey.getType().equals("2")){
            System.err.println(aHomeUser1.getStartTime());
            System.err.println(aHomeUser1.getEndTime());
            //卡片
            Long beginTime = aHomeUser1.getStartTime() == null ? null : aHomeUser1.getStartTime().getTime() / 1000;
            Long endTime = aHomeUser1.getEndTime() == null ? null : aHomeUser1.getEndTime().getTime() / 1000;
            ABuildHome aBuildHome = aBuildHomeService.selectABuildHomeById2(aTenantkey.getHomeId());


            if (aHomeUser1!=null){
                String keyGroupId2 = aHomeUser1.getKeyGroupId();
                if(StringUtils.isNotEmpty(keyGroupId2)){
                    keyGroupId3=keyGroupId2;
                }
            }

            JSONObject jsonObject = lockApiService.apartmentAddCardKey(
                    aBuildHome.getRoomNum(),
                    aTenantuser.getPhone(),
                    aTenantuser.getName(),
                    beginTime,
                    endTime,
                    aTenantuser.getCardNo(),
                    keyGroupId3
                    ,aTenantuser.getIdCardNumber()
                    );

            int resultCode = jsonObject.getIntValue("resultCode");
            if (resultCode != 0) {
                String reason = jsonObject.getString("reason");
                // 你可以根据不同的错误码自定义提示
                switch (resultCode) {
                    case 500001:
                        throw new RuntimeException("参数异常: " + reason);
                    case 500002:
                        throw new RuntimeException("房间不存在: " + reason);
                    case 500003:
                        throw new RuntimeException("房间未关好门锁: " + reason);
                    case 500004:
                        throw new RuntimeException("卡号不能为空: " + reason);
                    case 500005:
                        throw new RuntimeException("卡号不合法: " + reason);
                    case 500006:
                        throw new RuntimeException("暂不支持该房间授权: " + reason);
                    default:
                        throw new RuntimeException("远程发卡失败: " + reason);
                }
            }

            // 获取keyId并存入
            String keyId = null;
            String keyGroupId = null;
            if (jsonObject.containsKey("data")) {
                JSONObject dataObj = jsonObject.getJSONObject("data");
                keyId = dataObj.getString("keyId");
                keyGroupId = dataObj.getString("keyGroupId");
            }
            aTenantkey.setKeyGroupId(keyGroupId);
            aTenantkey.setPwdId(keyId);
            //往key表插入数据
            aTenantkey.setStatus(0);
            aTenantkey.setRemark("下发授权");
            // 在插入aTenantkey之前，更新AHomeUser的keyGroupId
            aHomeUserService.updateKeyGroupIdByHomeIdAndUserId(aTenantkey.getHomeId(),aTenantkey.getTenantId(),keyGroupId);

        }

        int result = aTenantkeyService.insertATenantkey(aTenantkey);


        return toAjax(result);
    }

    /**
     * 批量新增钥匙
     */
    @PreAuthorize("@ss.hasPermi('lock:tenantkey:add')")
    @Log(title = "批量钥匙", businessType = BusinessType.INSERT)
    @PostMapping("/batch")
    public AjaxResult batchAdd(@RequestBody BatchAddTenantkeyDto batchData)
    {
        try {
            // 获取基础信息和房间列表
            ATenantkey baseInfo = batchData.getBaseInfo();
            List<BatchAddTenantkeyDto.RoomInfo> rooms = batchData.getRooms();
            
            if (rooms == null || rooms.isEmpty()) {
                return error("房间信息不能为空");
            }
            
            // 构建socketId：用户ID_业务名
            String socketId = baseInfo.getTenantId() + "_key_auth";
            
            // 异步处理并通过WebSocket推送进度
            CompletableFuture.runAsync(() -> {
                processBatchAddWithWebSocket(batchData, socketId);
            }, customExecutor);
            
            // 立即返回成功响应
            return success("办理钥匙请求已接收，正在后台处理中");
            
        } catch (Exception e) {
            return error("批量添加失败: " + e.getMessage());
        }
    }
    
    /**
     * 处理单个房间的钥匙添加
     */
    private Map<String, Object> processRoom(BatchAddTenantkeyDto.RoomInfo room, ATenantkey baseInfo) {
        Map<String, Object> roomResult = new HashMap<>();
        roomResult.put("homeId", room.getHomeId());
        roomResult.put("cellId", room.getCellId());
        roomResult.put("unitId", room.getUnitId());
        roomResult.put("floorId", room.getFloorId());
        
        // 查询房间相关信息，用于失败时显示名称
        String roomName = "-";
        String cellName = "-";
        String unitName = "-";
        String floorName = "-";
        
        try {
            // 查询房间信息，应该包含了所有相关信息
            if (room.getHomeId() != null) {
                ABuildHome home = aBuildHomeService.selectABuildHomeById(room.getHomeId());
                if (home != null) {
                    roomName = home.getRoomName() != null ? home.getRoomName() : room.getHomeId().toString();
                    // 如果home对象中已经包含了区域、栋、层信息，直接使用
                    if (home.getCellName() != null) {
                        cellName = home.getCellName();
                    }
                    if (home.getUnitName() != null) {
                        unitName = home.getUnitName();
                    }
                    if (home.getFloorName() != null) {
                        floorName = home.getFloorName();
                    }
                }
            }
        } catch (Exception e) {
            // 查询名称失败时，使用ID作为名称
            roomName = room.getHomeId() != null ? room.getHomeId().toString() : "-";
            cellName = room.getCellId() != null ? room.getCellId().toString() : "-";
            unitName = room.getUnitId() != null ? room.getUnitId().toString() : "-";
            floorName = room.getFloorId() != null ? room.getFloorId().toString() : "-";
        }
        
        // 将名称信息保存到结果中
        roomResult.put("roomName", roomName);
        roomResult.put("cellName", cellName);
        roomResult.put("unitName", unitName);
        roomResult.put("floorName", floorName);
        
        try {
            // 构建钥匙对象
            ATenantkey aTenantkey = new ATenantkey();
            
            // 设置基础信息
            aTenantkey.setTenantId(baseInfo.getTenantId());
            aTenantkey.setType(baseInfo.getType());
            aTenantkey.setStartTime(baseInfo.getStartTime());
            aTenantkey.setEndTime(baseInfo.getEndTime());
            aTenantkey.setPassword(baseInfo.getPassword());
            aTenantkey.setUserName(baseInfo.getUserName());
            aTenantkey.setUserPhone(baseInfo.getUserPhone());
            aTenantkey.setRelation(baseInfo.getRelation());
            aTenantkey.setRemark(baseInfo.getRemark() != null ? baseInfo.getRemark() : "");
            
            // 设置房间信息
            aTenantkey.setHomeId(room.getHomeId());
            aTenantkey.setCellId(room.getCellId());
            aTenantkey.setUnitId(room.getUnitId());
            aTenantkey.setFloorId(room.getFloorId());
            
            // 如果是卡片类型，设置卡号
            if ("2".equals(baseInfo.getType())) {
                aTenantkey.setCardNo(baseInfo.getPassword());
            }
            
            // 验证结束时间不早于开始时间
            if (aTenantkey.getEndTime().before(aTenantkey.getStartTime()) || aTenantkey.getEndTime().equals(aTenantkey.getStartTime())) {
                throw new RuntimeException("结束时间不能早于或等于开始时间");
            }
            
            // 检查卡片类型时，验证卡号是否已在该房间中存在
            if ("2".equals(aTenantkey.getType()) && StringUtils.isNotEmpty(aTenantkey.getCardNo())) {
                ATenantkey checkKey = new ATenantkey();
                checkKey.setHomeId(aTenantkey.getHomeId());
                checkKey.setCardNo(aTenantkey.getCardNo());
                checkKey.setType("2"); // 卡片类型

                List<ATenantkey> existingKeys = aTenantkeyService.selectATenantkeySimple(checkKey);
                
                if (existingKeys != null && !existingKeys.isEmpty()) {
                    throw new RuntimeException("该房间中已存在此卡号，请勿重复办理");
                }
            }
            
            // 处理密码或卡片授权逻辑
            JSONObject data = new JSONObject();
            ATenantuser aTenantuser = aTenantuserService.selectATenantuserById(aTenantkey.getTenantId());
            AHomeUser aHomeUser = new AHomeUser();
            aHomeUser.setHomeId(aTenantkey.getHomeId());
            aHomeUser.setUserId(aTenantkey.getTenantId());
            String keyGroupId3 = null;
            
            AHomeUser aHomeUser1 = aHomeUserMapper.selectAHomeUserList2(aHomeUser);
            
            if (aTenantkey.getType().equals("1")) {
                // 密码
                data.put("method", "addPwd");
                data.put("pwd", Integer.parseInt(aTenantkey.getPassword()));
                data.put("start", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, aHomeUser1.getStartTime()));
                data.put("end", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, aHomeUser1.getEndTime()));
            }
            
            if (aTenantkey.getType().equals("2")) {
                // 卡片
                Long beginTime = aHomeUser1.getStartTime() == null ? null : aHomeUser1.getStartTime().getTime() / 1000;
                Long endTime = aHomeUser1.getEndTime() == null ? null : aHomeUser1.getEndTime().getTime() / 1000;
                ABuildHome aBuildHome = aBuildHomeService.selectABuildHomeById2(aTenantkey.getHomeId());
                
                if (aHomeUser1 != null) {
                    String keyGroupId2 = aHomeUser1.getKeyGroupId();
                    if (StringUtils.isNotEmpty(keyGroupId2)) {
                        keyGroupId3 = keyGroupId2;
                    }
                }
                
                JSONObject jsonObject = lockApiService.apartmentAddCardKey(
                        aBuildHome.getRoomNum(),
                        aTenantuser.getPhone(),
                        aTenantuser.getName(),
                        beginTime,
                        endTime,
                        aTenantuser.getCardNo(),
                        keyGroupId3,
                        aTenantuser.getIdCardNumber()
                );
                
                int resultCode = jsonObject.getIntValue("resultCode");
                if (resultCode != 0) {
                    String reason = jsonObject.getString("reason");
                    switch (resultCode) {
                        case 500001:
                            throw new RuntimeException("参数异常: " + reason);
                        case 500002:
                            throw new RuntimeException("房间不存在: " + reason);
                        case 500003:
                            throw new RuntimeException("房间未关好门锁: " + reason);
                        case 500004:
                            throw new RuntimeException("卡号不能为空: " + reason);
                        case 500005:
                            throw new RuntimeException("卡号不合法: " + reason);
                        case 500006:
                            throw new RuntimeException("暂不支持该房间授权: " + reason);
                        default:
                            throw new RuntimeException("远程发卡失败: " + reason);
                    }
                }
                
                // 获取keyId并存入
                String keyId = null;
                String keyGroupId = null;
                if (jsonObject.containsKey("data")) {
                    JSONObject dataObj = jsonObject.getJSONObject("data");
                    keyId = dataObj.getString("keyId");
                    keyGroupId = dataObj.getString("keyGroupId");
                }
                aTenantkey.setKeyGroupId(keyGroupId);
                aTenantkey.setPwdId(keyId);
                aTenantkey.setStatus(0);
                aTenantkey.setRemark("下发授权");
                // 在插入aTenantkey之前，更新AHomeUser的keyGroupId
                aHomeUserService.updateKeyGroupIdByHomeIdAndUserId(aTenantkey.getHomeId(), aTenantkey.getTenantId(), keyGroupId);
            }
            
            // 插入钥匙记录
            int result = aTenantkeyService.insertATenantkey(aTenantkey);
            if (result > 0) {
                roomResult.put("status", "success");
                roomResult.put("message", "添加成功");
            } else {
                roomResult.put("status", "failed");
                roomResult.put("message", "数据库插入失败");
            }
            
        } catch (Exception e) {
            roomResult.put("status", "failed");
            roomResult.put("message", e.getMessage());
        }
        
        return roomResult;
    }
    
    /**
     * 异步处理批量添加钥匙并通过WebSocket推送进度
     */
    private void processBatchAddWithWebSocket(BatchAddTenantkeyDto batchData, String socketId) {
        try {
            ATenantkey baseInfo = batchData.getBaseInfo();
            List<BatchAddTenantkeyDto.RoomInfo> rooms = batchData.getRooms();
            
            int total = rooms.size();
            int current = 0;
            int successCount = 0;
            int failCount = 0;
            
            // 发送开始处理的消息
            sendWebSocketMessage(socketId, "key_auth_progress", current, total, "开始处理办理钥匙请求...");
            
            for (BatchAddTenantkeyDto.RoomInfo room : rooms) {
                current++;
                
                try {
                    // 处理单个房间
                    Map<String, Object> roomResult = processRoom(room, baseInfo);
                    
                    if ("success".equals(roomResult.get("status"))) {
                        successCount++;
                        // 成功只显示进度，不推送详细信息
                        sendWebSocketMessage(socketId, "key_auth_progress", current, total, 
                            String.format("已处理 %d/%d", current, total));
                    } else {
                        failCount++;
                        // 失败才推送详细信息到前端，使用从processRoom返回的名称信息
                        Map<String, Object> progressData = new HashMap<>();
                        progressData.put("roomName", roomResult.get("roomName"));
                        progressData.put("cellName", roomResult.get("cellName"));
                        progressData.put("unitName", roomResult.get("unitName"));
                        progressData.put("floorName", roomResult.get("floorName"));
                        progressData.put("keyType", "1".equals(baseInfo.getType()) ? "密码" : "卡片");
                        progressData.put("message", roomResult.get("message").toString());
                        
                        sendWebSocketMessage(socketId, "key_auth_progress", current, total, 
                            String.format("房间 %s 办理钥匙失败: %s", roomResult.get("roomName"), roomResult.get("message")), progressData);
                    }
                    
                } catch (Exception e) {
                    failCount++;
                    // 异常也推送详细信息到前端，需要查询名称信息
                    Map<String, Object> progressData = new HashMap<>();
                    
                    // 查询房间相关信息
                    String roomName = "-";
                    String cellName = "-";
                    String unitName = "-";
                    String floorName = "-";
                    
                    try {
                        // 查询房间信息，应该包含了所有相关信息
                        if (room.getHomeId() != null) {
                            ABuildHome home = aBuildHomeService.selectABuildHomeById(room.getHomeId());
                            if (home != null) {
                                roomName = home.getRoomName() != null ? home.getRoomName() : room.getHomeId().toString();
                                // 如果home对象中已经包含了区域、栋、层信息，直接使用
                                if (home.getCellName() != null) {
                                    cellName = home.getCellName();
                                }
                                if (home.getUnitName() != null) {
                                    unitName = home.getUnitName();
                                }
                                if (home.getFloorName() != null) {
                                    floorName = home.getFloorName();
                                }
                            }
                        }
                    } catch (Exception ex) {
                        // 查询名称失败时，使用ID作为名称
                        roomName = room.getHomeId() != null ? room.getHomeId().toString() : "-";
                        cellName = room.getCellId() != null ? room.getCellId().toString() : "-";
                        unitName = room.getUnitId() != null ? room.getUnitId().toString() : "-";
                        floorName = room.getFloorId() != null ? room.getFloorId().toString() : "-";
                    }
                    
                    progressData.put("roomName", roomName);
                    progressData.put("cellName", cellName);
                    progressData.put("unitName", unitName);
                    progressData.put("floorName", floorName);
                    progressData.put("keyType", "1".equals(baseInfo.getType()) ? "密码" : "卡片");
                    progressData.put("message", "处理异常: " + e.getMessage());
                    
                    sendWebSocketMessage(socketId, "key_auth_progress", current, total, 
                        String.format("房间 %s 处理异常: %s", roomName, e.getMessage()), progressData);
                }
                
                // 添加延迟，避免消息发送过快
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            
            // 发送完成消息
            Map<String, Object> finalResult = new HashMap<>();
            finalResult.put("totalRooms", total);
            finalResult.put("successCount", successCount);
            finalResult.put("failCount", failCount);
            
            if (failCount == 0) {
                sendWebSocketMessage(socketId, "key_auth_complete", total, total, 
                    String.format("办理钥匙完成！成功处理 %d 个房间", successCount), finalResult);
            } else {
                sendWebSocketMessage(socketId, "key_auth_complete", total, total, 
                    String.format("办理钥匙完成！成功 %d 个，失败 %d 个", successCount, failCount), finalResult);
            }
            
        } catch (Exception e) {
            // 发送错误消息
            sendWebSocketMessage(socketId, "key_auth_error", 0, 0, "办理钥匙处理异常: " + e.getMessage());
        }
    }
    
    /**
     * 发送WebSocket消息
     */
    private void sendWebSocketMessage(String socketId, String type, int current, int total, String message) {
        sendWebSocketMessage(socketId, type, current, total, message, null);
    }
    
    /**
     * 发送WebSocket消息（带数据）
     */
    private void sendWebSocketMessage(String socketId, String type, int current, int total, String message, Object data) {
        try {
            // 构建WebSocket消息
            JSONObject wsMessage = new JSONObject();
            wsMessage.put("type", type);
            wsMessage.put("current", current);
            wsMessage.put("total", total);
            wsMessage.put("message", message);
            if (data != null) {
                wsMessage.put("data", data);  // 这里包含了所有的名字信息
            }
            
            // 解析socketId获取用户ID
            String[] parts = socketId.split("_");
            if (parts.length >= 2) {
                Long userId = Long.valueOf(parts[0]);
                
                // 通过WebSocket服务发送消息
                WebSocketEndpoint.sendMessageToUser(userId, wsMessage.toJSONString());
            }
            
        } catch (Exception e) {
            logger.error("发送WebSocket消息失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 清空卡片
     */
    @Log(title = "钥匙", businessType = BusinessType.DELETE)
    @DeleteMapping("/delKeyClearPwd")
    @Transactional
    public AjaxResult delKeyClearPwd(@RequestParam("mac") String mac)
    {

        //构建data
        JSONObject data = new JSONObject();
        data.put("method","clearPwd");

        //存进task表
        ATask aTask = new ATask();
        aTask.setData(data.toString());
        aTask.setTarTable("a_tenantkey");
        aTask.setDid(mac);
        aTask.setUserId(SecurityUtils.getUserId());
        aTask.setType("clearPwd");
        int i = taskMapper.insertATask(aTask);


        ATenantkey aTenantkey1 = new ATenantkey();
        aTenantkey1.setMac(mac);
        aTenantkey1.setStatus(0);
        aTenantkey1.setFlgDelete(0);
        aTenantkey1.setRemark("密码清除");
        aTenantkey1.setType("1");
        int result = aTenantkeyService.updateATenantkeyHomeId(aTenantkey1);


        return toAjax(i);
    }
    /**
     * 清空卡片
     */
    @Log(title = "钥匙", businessType = BusinessType.DELETE)
    @DeleteMapping("/delKeyClearCard")
    @Transactional
    public AjaxResult delKeyClearCard(@RequestParam("mac") String mac)
    {
        //构建data
        JSONObject data = new JSONObject();
        data.put("method","clearCard");

        //存进task表
        ATask aTask = new ATask();
        aTask.setData(data.toString());
        aTask.setTarTable("a_tenantkey");
        aTask.setDid(mac);
        aTask.setUserId(SecurityUtils.getUserId());
        aTask.setType("clearCard");
        int i = taskMapper.insertATask(aTask);


        ATenantkey aTenantkey1 = new ATenantkey();
        aTenantkey1.setMac(mac);
        aTenantkey1.setStatus(0);
        aTenantkey1.setFlgDelete(0);
        aTenantkey1.setRemark("清空卡片");
        aTenantkey1.setType("2");
        int result = aTenantkeyService.updateATenantkeyMac(aTenantkey1);
        return toAjax(i);
    }
    /**
     * 修改钥匙
     */
    @PreAuthorize("@ss.hasPermi('lock:tenantkey:edit')")
    @Log(title = "钥匙", businessType = BusinessType.UPDATE)
    @PutMapping
    @Transactional
    public AjaxResult edit(@RequestBody ATenantkey aTenantkey)
    {

        return toAjax(aTenantkeyService.updateATenantkey(aTenantkey));
    }


    @PreAuthorize("@ss.hasPermi('lock:tenantkey:edit')")
    @Log(title = "钥匙", businessType = BusinessType.UPDATE)
    @PutMapping("/updateKey")
    @Transactional
    public AjaxResult updateKey(@RequestBody ATenantkey aTenantkey)
    {

        ATenantkey aTenantkey2 = new ATenantkey();
        aTenantkey2.setMac(aTenantkey.getMac());
        aTenantkey2.setPassword(aTenantkey.getPassword());

        List<ATenantkey> list = aTenantkeyService.selectATenantkeyList3(aTenantkey2);
        if (list.size()>0){
            throw new RuntimeException("密码已经存在请更换一个密码!");
        }

        ATenantkey aTenantkey1 = aTenantkeyService.selectATenantkeyById(aTenantkey.getId());

        ATenantkey aKey1 = new ATenantkey();
        aKey1.setId(aTenantkey.getId());
        aKey1.setPassword(aTenantkey.getPassword());
        aKey1.setStatus(0);


        //构建data
        JSONObject data = new JSONObject();

            data.put("method","modifyPwd");
            data.put("pwdId",aTenantkey1.getPwdId());
            data.put("pwd",Integer.parseInt(aTenantkey.getPassword()));



        data.put("start",DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,aTenantkey1.getStartTime()));
        data.put("end", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,aTenantkey1.getEndTime()));
        //存进task表
        ATask aTask = new ATask();
        aTask.setData(data.toString());
        aTask.setTarId(aTenantkey1.getId());
        aTask.setTarTable("a_key");
        aTask.setDid(aTenantkey1.getMac());
        aTask.setType("modifyPwd");
        aTask.setUserId(SecurityUtils.getUserId());
        int i = aTenantkeyService.updateATenantkey(aKey1);
        int result = taskMapper.insertATask(aTask);
        return toAjax(result);
    }



    @PreAuthorize("@ss.hasPermi('lock:tenantkey:edit')")
    @Log(title = "钥匙", businessType = BusinessType.UPDATE)
    @PutMapping("/updateDate")
    @Transactional
    public AjaxResult updateDate(@RequestBody ATenantkey aTenantkey)
    {
        // 验证结束时间不早于开始时间
        if (aTenantkey.getEndTime().before(aTenantkey.getStartTime()) || aTenantkey.getEndTime().equals(aTenantkey.getStartTime())) {
            return error("结束时间不能早于或等于开始时间");
        }
        ATenantkey aTenantkey2 = new ATenantkey();
        aTenantkey2.setMac(aTenantkey.getMac());
        aTenantkey2.setPassword(aTenantkey.getPassword());


        ATenantkey aTenantkey1 = aTenantkeyService.selectATenantkeyById(aTenantkey.getId());

        ATenantkey aKey1 = new ATenantkey();
        aKey1.setId(aTenantkey.getId());
        aKey1.setStatus(0);
        aKey1.setStartTime(aTenantkey.getStartTime());
        aKey1.setEndTime(aTenantkey.getEndTime());

        //构建data
        JSONObject data = new JSONObject();
        if("1".equals(aTenantkey1.getType())){
            data.put("method","modifyPwd");
            data.put("pwdId",aTenantkey1.getPwdId());
            data.put("pwd",Integer.parseInt(aTenantkey1.getPassword()));

        }else if ("2".equals(aTenantkey1.getType())){
            data.put("method","modifyCard");
            data.put("cardId",aTenantkey1.getPwdId());
        }

        data.put("start",DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,aTenantkey.getStartTime()));
        data.put("end", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,aTenantkey.getEndTime()));
        //存进task表
        ATask aTask = new ATask();
        aTask.setData(data.toString());
        aTask.setTarId(aTenantkey1.getId());
        aTask.setTarTable("a_key");
        aTask.setDid(aTenantkey1.getMac());
        aTask.setType("modifyPwd");
        aTask.setUserId(SecurityUtils.getUserId());
        int i = aTenantkeyService.updateATenantkey(aKey1);
        int result = taskMapper.insertATask(aTask);
        return toAjax(result);
    }

    /**
     * 删除钥匙
     */
    @PreAuthorize("@ss.hasPermi('lock:tenantkey:remove')")
    @Log(title = "钥匙", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @Transactional
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        try {
            int successCount = 0;
            for (Long id : ids) {
                // 获取密钥信息
                ATenantkey aTenantkey = aTenantkeyService.selectATenantkeyById(id);
                if (aTenantkey == null) {
                    continue; // 如果ID无效，跳过此次循环
                }
                successCount += aTenantkeyService.deleteATenantkeyAndCreateTask(aTenantkey);
            }
            return toAjax(successCount==0?1:successCount);
        } catch (Exception e) {
            logger.error("删除钥匙失败", e);
            return error("删除钥匙失败: " + e.getMessage());
        }
    }

    /**
     * 冻结/解冻密码
     */
    @PreAuthorize("@ss.hasPermi('lock:tenantkey:edit')")
    @Log(title = "钥匙", businessType = BusinessType.UPDATE)
    @PutMapping("/freezePwd")
    @Transactional
    public AjaxResult freezePwd(@RequestBody ATenantkey aTenantkey) {
        if (aTenantkey.getPwdId() == null) {
            return error("密码ID不存在，无法进行冻结/解冻操作");
        }

        // 修改为待生效
        ATenantkey updateKey = new ATenantkey();
        updateKey.setId(aTenantkey.getId());
        updateKey.setStatus(0);
        updateKey.setIsItAvailable(aTenantkey.getIsItAvailable());
        aTenantkeyService.updateATenantkey(updateKey);

        //构建data
        JSONObject data = new JSONObject();
        data.put("method", "freezePwd");
        data.put("pwdId", aTenantkey.getPwdId());
        data.put("status", aTenantkey.getIsItAvailable());

        //存进task表
        ATask aTask = new ATask();
        aTask.setData(data.toString());
        aTask.setTarId(aTenantkey.getId());
        aTask.setTarTable("a_key");
        aTask.setDid(aTenantkey.getMac());
        aTask.setType(aTenantkey.getIsItAvailable() == 1 ? "unfreezePwd" : "freezePwd");
        aTask.setUserId(SecurityUtils.getUserId());
        int result = taskMapper.insertATask(aTask);

        return toAjax(result);
    }

    /**
     * 冻结/解冻卡片
     */
    @PreAuthorize("@ss.hasPermi('lock:tenantkey:edit')")
    @Log(title = "钥匙", businessType = BusinessType.UPDATE)
    @PutMapping("/freezeCard")
    @Transactional
    public AjaxResult freezeCard(@RequestBody ATenantkey aTenantkey)
    {
        if (aTenantkey.getPwdId() == null) {
            return error("卡片ID不存在，无法进行冻结/解冻操作");
        }

        // 修改为待生效
        ATenantkey updateKey = new ATenantkey();
        updateKey.setId(aTenantkey.getId());
        updateKey.setStatus(0);
        updateKey.setIsItAvailable(aTenantkey.getIsItAvailable());
        aTenantkeyService.updateATenantkey(updateKey);

        //构建data
        JSONObject data = new JSONObject();
        data.put("method",  "freezeCard");
        data.put("cardId", aTenantkey.getPwdId());
        data.put("status", aTenantkey.getIsItAvailable());

        //存进task表
        ATask aTask = new ATask();
        aTask.setData(data.toString());
        aTask.setTarId(aTenantkey.getId());
        aTask.setTarTable("a_key");
        aTask.setDid(aTenantkey.getMac());
        aTask.setType(aTenantkey.getIsItAvailable() == 1 ? "freezeCard" : "unfreezeCard");
        aTask.setUserId(SecurityUtils.getUserId());
        int result = taskMapper.insertATask(aTask);

        return toAjax(result);
    }

    public static String aesEncrypt(String tokenId, String cardNum) throws Exception {
        // 1. 取tokenId的MD5，转16进制字符串
        byte[] md5Byte = MessageDigest.getInstance("MD5").digest(tokenId.getBytes());
        StringBuilder sb = new StringBuilder(md5Byte.length * 2);
        for (byte b : md5Byte) {
            sb.append(Character.toUpperCase(Character.forDigit((b >> 4) & 0x0F, 16)));
            sb.append(Character.toUpperCase(Character.forDigit(b & 0x0F, 16)));
        }
        String hexStr = sb.toString();
        String aesKey = hexStr.substring(8, 24);
        // 2. 卡号补齐10位
        String cardNum10 = String.format("%010d", Long.parseLong(cardNum));
        // 3. AES加密
        IvParameterSpec zeroIv = new IvParameterSpec(aesKey.getBytes());
        SecretKeySpec key = new SecretKeySpec(aesKey.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
        byte[] encrypted = cipher.doFinal(cardNum10.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encrypted);
    }
}
